#include "GeomBuilder.h"
#include "RandomUtil.h"
#include <math.h>
#include <cstdlib>
#include <stdio.h>
#include <iostream> 

GeomNode* BuildTriangle(float length) 
{
	return new TriangleNode(length);
}

GeomNode* BuildCappedCylinder(float fRadius1, float fHight, int iNumSides)
{
	return new CylinderNode(fRadius1, fRadius1, fHight, iNumSides);
}

GeomNode* BuildCylinder(float radius, float hight, int numSides)
{
	int res = numSides*2;
	Vertex* pVertArray = new Vertex[res];
	short* pIndexArray = new short[res*3];
	for(int i = 0; i < res/2; i++)
    {
        float theta = ( 2 * D3DX_PI * i ) / ( res/2 - 1 );
        pVertArray[2 * i + 0].SetPos(&D3DXVECTOR3(radius * sinf(theta), 0.0f, radius * cosf(theta)));
        pVertArray[2 * i + 0].SetNorm(&D3DXVECTOR3(radius * sinf(theta), 0.0f, radius * cosf(theta)));
        pVertArray[2 * i + 1].SetPos(&D3DXVECTOR3(radius * sinf(theta), hight, radius * cosf(theta)));
        pVertArray[2 * i + 1].SetNorm(&D3DXVECTOR3(radius * sinf(theta), 0.0f, radius * cosf(theta)));
	}
	for(int i = 0; i < res; i++)
	{
		pIndexArray[3*i] = i%res;
		pIndexArray[3*i+1] = (i+1)%res;
		pIndexArray[3*i+2] = (i+2)%res;
	}
	return new ArbGeomNode(pVertArray, res, pIndexArray, res*3);
}
GeomNode* BuildGrid(Vertex* pVerts, int n)
{
	int side = (int)sqrt((double)n);
	int size = (side-1)*(side-1)*6;
	short* pIndexArray = new short[size];
	for(int i = 0; i < (side-1); i++)
	{
		for(int j = 0; j < (side-1); j++)
		{
			pIndexArray[6*(side-1)*i+6*j] = side * i + j;
			pIndexArray[6*(side-1)*i+6*j+1] = side * i + j + 1;
			pIndexArray[6*(side-1)*i+6*j+2] = side * i + j + side;
			pIndexArray[6*(side-1)*i+6*j+3] = side * i + j +1;
			pIndexArray[6*(side-1)*i+6*j+4] = side * i + j + side;
			pIndexArray[6*(side-1)*i+6*j+5] = side * i + j + side + 1;
		}
	}
	return new ArbGeomNode(pVerts, n, pIndexArray, size);
}
GeomNode* BuildSphere(float fRadius, int iNumSlices, int iNumStacks)
{
	return new SphereNode(fRadius, iNumSlices, iNumStacks);
}

GeomNode* BuildTri(Vect3D P1, Vect3D P2, Vect3D P3)
{
	//TODO: Make these normals calculate correctly.
	Vertex* pVerts = new Vertex[3];
	short* pIndexArray = new short[3];
	D3DXVECTOR3 * norm = &D3DXVECTOR3((float)RandomUtil::random(0,5),(float)RandomUtil::random(0,5),(float)RandomUtil::random(0,5));
		//getTriangleNormal(&D3DXVECTOR3(P1.x,P1.y,P1.z),&D3DXVECTOR3(P2.x,P2.y,P2.z),&D3DXVECTOR3(P3.x,P3.y,P3.z));
	pVerts[0].SetPos(&D3DXVECTOR3(P1.x,P1.y,P1.z));
	pVerts[0].SetNorm(norm);
	pVerts[1].SetPos(&D3DXVECTOR3(P2.x,P2.y,P2.z));
	pVerts[1].SetNorm(norm);
	pVerts[2].SetPos(&D3DXVECTOR3(P3.x,P3.y,P3.z));
	pVerts[2].SetNorm(norm);
	pIndexArray[0] = 0;
	pIndexArray[1] = 1;
	pIndexArray[2] = 2;
	return new ArbGeomNode(pVerts, 3, pIndexArray, 3);
}

D3DXVECTOR3 * getTriangleNormal(D3DXVECTOR3* vVertex1, D3DXVECTOR3* vVertex2, D3DXVECTOR3* vVertex3)
{
    D3DXVECTOR3 vNormal;
    D3DXVECTOR3 v1;
    D3DXVECTOR3 v2;


    D3DXVec3Subtract(&v1, vVertex2, vVertex1);
    D3DXVec3Subtract(&v2, vVertex3, vVertex1);

    D3DXVec3Cross(&vNormal, &v1, &v2);
	//D3DXVec3Cross(&vNormal, &vNormal, &v2);

    D3DXVec3Normalize(&vNormal, &vNormal);

    return &vNormal;
}


GeomNode* BuildArbObj(Vertex* pVerts, int nV, short* pIndexArray, int nI)
{
	return new ArbGeomNode(pVerts, nV, pIndexArray, nI);
}




